/*
Copyright (c) 2007
Daniel Yang (daniel.yang.zhenyu at gmail.com)
Zh Su
All rights reserved.
Thanks to EarthPlayer.com and Silver.


Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
    Redistributions of source code must retain the above copyright notice,
    this list of conditions and the following disclaimer.
    Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.
    Neither the name of Stamen Design, Look or Feel, nor the names of its
    contributors may be used to endorse or promote products derived from
    this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package cn.funcat.map.layer
{
	import cn.funcat.map.tile.Eds2DTileContext;
	import cn.funcat.map.tile.Eds3DTileContext;
	import cn.funcat.map.tile.IMapTile;
	import cn.funcat.map.tile.MapTile;
	import cn.funcat.map.tile.TileContextBase;
	import cn.funcat.util.FunCatConsts;
	
	import flash.geom.Rectangle;
	
	import mx.core.ClassFactory;
	import mx.core.IDataRenderer;
	import mx.core.IFactory;
	import mx.core.UIComponent;
	
	
	/**
	 * edushi层
	 * @author daniel
	 * 
	 */ 
	public class EdsMapLayer extends LayerBase
	{		
		private var _currentTileRect:Rectangle;
		private var _currentTileContext:TileContextBase;
		
		public function EdsMapLayer()
		{
			super();
			//we don't need dataProvider here and only here.
			_itemRenderer = new ClassFactory(MapTile);
			
			_currentTileRect = new Rectangle();
			_currentTileContext = new Eds3DTileContext();
		}
		
		/**
		 * 3d
		 * 
		 */		
		public function show3DMap():void{
			if(_currentTileContext is Eds3DTileContext) return;
			_currentTileContext = new Eds3DTileContext();
			for(var i:int = 0; i < this.numChildren;i++) {
				var tile:MapTile = this.getChildAt(i) as MapTile;
				tile.tileContext = _currentTileContext;
			}
			
		}
		
		/**
		 * 2d
		 * 
		 */		
		public function show2DMap():void{
			if(_currentTileContext is Eds2DTileContext) return;
			_currentTileContext = new Eds2DTileContext();
			for(var i:int = 0; i < this.numChildren;i++) {
				var tile:MapTile = this.getChildAt(i) as MapTile;
				tile.tileContext = _currentTileContext;
			}
			
		}
		
		/**
		 *  删除显示不到的图片
		 * @param toShow 需要显示的区域
		 * @param zoom 
		 * 
		 */		
		private function removeImages(toShow:Rectangle, zoom:Number):void{
			trace("Before: " + this.numChildren);
			for(var i:int = 0; i < this.numChildren;i++) {
				var tile:MapTile = this.getChildAt(i) as MapTile;
				if(!tile.inUse){
					this.removeChildAt(i);
				}
			}
			trace("After: " + this.numChildren);
			
		}
		
		/**
		 * 删除所有图片
		 * 
		 */		
		private function removeAllImages():void{
			//或许会异常
			/* for(var m:int = 0; m < this.numChildren;m++) {
				this.removeChildAt(m);
			} */
			
			//最好不要这样删除.
			while(this.numChildren!=0){
				this.removeChildAt(0);
			}
			
			//还可以从后向前删除...
			//还可以...
		}
		
		/**
		 * 加载图片
		 * @param toShow
		 * @param zoom
		 * 
		 */		
		private function loadImages(toShow:Rectangle, zoom:Number):void{
			//make sure tiles in toShow aria is inUse.
			for(var i:Number= toShow.left; i <= toShow.right; i++){
				for(var m:Number = toShow.top; m <= toShow.bottom; m++){
					var _tileData:Object = {x : i, y : m, z: zoom};

					//check if exists.
					var tile:MapTile;
					var k:String = (this._currentTileContext is Eds3DTileContext) ? "3d" : "2d";
					tile = getTileByID(k+ "_" + i + "_" + m + "_" + zoom);
					if(!tile){
						tile = _itemRenderer.newInstance();
						addChild(tile);
						IDataRenderer(tile).data = _tileData;
						IMapTile(tile).tileContext = _currentTileContext;
					}

					tile.inUse = true;
				}
			}

			invalidateDisplayList();						
		}
		
		/**
		 * 通过ID获得图片
		 * @param id
		 * @return 
		 * 
		 */		
		private function getTileByID(id:String):MapTile{
			for(var i:int = 0; i < this.numChildren;i++) {
				var tile:MapTile = this.getChildAt(i) as MapTile;
				if(tile.id==id){
					return tile;
				}
			}
			return null;
		}
		
		/**
		 * set dirty
		 * 
		 */		
		private function setFlase():void{
			for(var i:int = 0; i < this.numChildren;i++) {
				var tile:MapTile = this.getChildAt(i) as MapTile;
				tile.inUse = false;
			}
		}
		
		/**
		 * 更新视图
		 * @param unscaledWidth
		 * @param unscaledHeight
		 * 
		 */		
		override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void{
			for(var i:int = 0; i < this.numChildren;i++) {
				var bmt:MapTile = MapTile(this.getChildAt(i));
				bmt.x = bmt.data.x * FunCatConsts.TILE_SIZE;
				bmt.y = bmt.data.y * FunCatConsts.TILE_SIZE;
			}
		}
		
		/**
		 *  可视范围改变,或者缩放改变
		 * @param rect
		 * @param z
		 * 
		 */		
		override public function changeViewRect(rect:Rectangle, z:Number):void{
			var _tileRect:Rectangle = new Rectangle();
			
			//从像素, 到Tile的Column, row的近似值.
			_tileRect.left = Math.round((rect.left-128)/256);
			_tileRect.right = Math.round((rect.right+128)/256);
			_tileRect.top = Math.round((rect.top-128)/256);
			_tileRect.bottom = Math.round((rect.bottom+128)/256);

			if(this._zoomLevel != z){
				this._zoomLevel = z;
				this.removeAllImages();
			}
			_currentTileRect = _tileRect;
			
			setFlase();	
			this.loadImages(_tileRect, z);
			this.removeImages(_tileRect, z);	
		}
		
		
	}
}